package drds.plus.executor.transaction;

import ch.qos.logback.WithLog;
import drds.plus.datanode.api.Connection;
import drds.plus.executor.ExecutorException;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public abstract class AbstractConnectionHolder implements drds.plus.executor.transaction.ConnectionHolder, WithLog {

    protected Set<Connection> connectionSet = Collections.synchronizedSet(new HashSet());
    protected boolean closed = false;

    public Set<Connection> getConnectionSet() {
        return this.connectionSet;
    }

    public void kill() {
        Set<Connection> connectionSet = this.getConnectionSet();
        for (Connection connection : connectionSet) {
            try {
                connection.kill();
            } catch (Exception e) {
                log().error("connection close failed, connection is " + connection, e);
            }
        }

        this.closeConnectionSet();
        this.closed = true;
    }

    public void cancel() {
        Set<Connection> connectionSet = this.getConnectionSet();
        for (Connection connection : connectionSet) {
            try {
                connection.cancelQuery();
            } catch (Exception e) {
                log().error("connection close failed, connection is " + connection, e);
            }
        }

    }

    protected void checkClosed() {
        if (!this.closed) {
            return;
        }

        throw new ExecutorException("connection holder is closed, cannot do any operations");
    }

    /**
     * 查询cancle掉之后，下次新的sql还能执行
     */

    public void restart() {
        this.closed = false;

    }

    public void closeConnectionSet() {
        Set<Connection> connectionSet = this.getConnectionSet();

        for (Connection connection : connectionSet) {
            try {
                connection.close();
            } catch (Exception e) {
                log().error("connection close failed, connection is " + connection, e);
            }
        }
        this.connectionSet.clear();
    }

}
